package com.virtualCat.util;

import com.google.common.collect.Maps;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder;
import com.virtualCat.common.WeChatConfig;
import com.virtualCat.vo.WxPaySendData;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

public class WeChatPayUtil {
    private static Log log = LogFactory.getLog(WeChatPayUtil.class);
    /**
     * 获取openid
     * @param code
     * @return
     */
    public static String wechatCode(String code){
        String jsonText ="";
        StringBuffer url=new StringBuffer("https://api.weixin.qq.com/sns/jscode2session?");
        url.append("appid=").append(WeChatConfig.APP_ID).append("&");
        url.append("secret=").append(WeChatConfig.APP_SECRET).append("&");
        url.append("js_code=").append(code).append("&");
        url.append("grant_type=authorization_code");
        log.info("授权开始地址："+url.toString());
        jsonText= Tools.getStaticString(url.toString());
        return jsonText;
    }

    /**
     * 获取微信签名
     * @param map 请求参数集合
     * @return 微信请求签名串
     */
    public static String createSign(SortedMap<String,Object> map){
        StringBuffer sb = new StringBuffer();
        Set set = map.entrySet();//所有参与传参的参数按照accsii排序（升序）
        Iterator iterator = set.iterator();
        while (iterator.hasNext()){
            Map.Entry entry = (Map.Entry) iterator.next();
            String k = (String) entry.getKey();
            Object v = entry.getValue();
            //参数中sign、key不参与签名加密
            if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)){
                sb.append(k + "=" + v + "&");
            }
        }
        sb.append("key=" + WeChatConfig.KEY);
        String sign = Md5Util.getMD5Byte(sb.toString()).toUpperCase();
        return sign;
    }

    /**
     * 获取微信签名
     * @param paramMap
     * @param key
     * @return
     */
    public static String getSign(Map<String,String> paramMap,String key){
        List list = new ArrayList(paramMap.keySet());
        Object[] ary = list.toArray();
        Arrays.sort(ary);
        list = Arrays.asList(ary);
        String str = "";
        for(int i=0;i<list.size();i++){
            str+=list.get(i)+"="+paramMap.get(list.get(i)+"")+"&";
        }
        str+="key="+key;
        str = Md5Util.getMD5Byte(str).toUpperCase();
        return str;
    }

    /**
     * 生成二维码地址
     * @param weixinInfoDTO
     * @return
     */
//    public static String generateCodeUrl(WeixinInfoDTO weixinInfoDTO){
//        String codeUrl = "";
//        String submitXml = buildWeixinXml(weixinInfoDTO);
//        String resultStr = getTradeOrder(SUBMIT_URL,submitXml);
//        if(StringUtils.isNotBlank(resultStr)){
//            try {
//                Map map = doXMLParse(resultStr);
//                codeUrl = (String)map.get("code_url");
//            } catch (Exception e) {
//                // TODO Auto-generated catch block
//                e.printStackTrace();
//            }
//        }
//        return codeUrl;
//    }



    /**
     * 扩展xstream,使其支持name带有"_"的节点
     */
    public static XStream xStream =
            new XStream(new DomDriver("UTF-8",new XmlFriendlyNameCoder("-_","_")));

    /**
     * 请求参数转换成xml
     * @param data
     * @return xml字符串
     */
    public static String sendDataToXml(WxPaySendData data){
        xStream.autodetectAnnotations(true);
        xStream.alias("xml", WxPaySendData.class);
        return xStream.toXML(data);
    }


    /**
     * 解析微信服务器发来的请求
     * @param inputStream
     * @return 微信返回的参数集合
     */
    public static SortedMap<String,Object> parseXml(InputStream inputStream) {
        SortedMap<String,Object> map = Maps.newTreeMap();
        try {
            //获取request输入流
            SAXReader reader = new SAXReader();
            Document document = reader.read(inputStream);
            //得到xml根元素
            Element root = document.getRootElement();
            //得到根元素所有节点
            List<Element> elementList = root.elements();
            //遍历所有子节点
            for (Element element:elementList){
                map.put(element.getName(),element.getText());
            }
            //释放资源
            inputStream.close();
        } catch (Exception e) {
            System.out.println(e.getStackTrace());
        }
        return map;
    }

    public static SortedMap<String,Object> parseXml(String xml) {
        SortedMap<String,Object> map = Maps.newTreeMap();
        try {
            //获取request输入流
            SAXReader reader = new SAXReader();
            Document document = reader.read(xml);
            //得到xml根元素
            Element root = document.getRootElement();
            //得到根元素所有节点
            List<Element> elementList = root.elements();
            //遍历所有子节点
            for (Element element:elementList){
                map.put(element.getName(),element.getText());
            }
        } catch (Exception e) {
            System.out.println(e.getStackTrace());
        }
        return map;
    }


    /**
     *  获取当前时间戳
     * @return 当前时间戳字符串
     */
    public static String getTimeStamp(){
        return String.valueOf(System.currentTimeMillis()/1000);
    }

    /**
     * 获取指定长度的随机字符串
     * @param length
     * @return 随机字符串
     */
    public static String getRandomStr(int length){
        String base = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }

    /**
     * 处理xml请求信息
     * @param request
     * @return
     */
    public static String getXmlRequest(HttpServletRequest request){
        java.io.BufferedReader bis = null;
        String result = "";
        try{
            bis = new java.io.BufferedReader(new java.io.InputStreamReader(request.getInputStream()));
            String line = null;
            while((line = bis.readLine()) != null){
                result += line;
            }
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            if(bis != null){
                try{
                    bis.close();
                }catch(IOException e){
                    e.printStackTrace();
                }
            }
        }
        return result;
    }



//    public static InputStream StringInputstream(String str) {
//        return new ByteArrayInputStream(str.getBytes());
//    }

}
